using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace KaroGame.FrontEnd
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Designations : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private SpriteBatch spriteBatch;
        private KaroGame baseGame;

        private SpriteFont designationsFont;

        const int centralIndexX = 10;
        const int centralIndexY = 8;
       
        public Designations(KaroGame game)
            : base(game)
        {
            baseGame = game;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
        }

        public new void LoadContent()
        {
            spriteBatch = baseGame.SpriteBatch;

            designationsFont = baseGame.Content.Load<SpriteFont>("Font/Designations");
        }
        
        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
        }

        private Vector2 GetXandYIndicesFromTileId(int Id)
        {
            Vector2 Indices = new Vector2();

            Indices.X = (Id+1) % 21;
            Indices.Y = (Id+1) / 21;

            return Indices;
        }
        
        public override void Draw(GameTime gameTime)
        {

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);

            Vector2 maxIndices = new Vector2(int.MinValue, int.MinValue);
            Vector2 minIndices = new Vector2(int.MaxValue, int.MaxValue);

            foreach (KaroTile tile in baseGame.GetTiles.Tiles.Values)
            {
                if (tile.Ghost == false)
                {
                    if (GetXandYIndicesFromTileId(tile.Id).X > maxIndices.X) maxIndices.X = GetXandYIndicesFromTileId(tile.Id).X;
                    if (GetXandYIndicesFromTileId(tile.Id).X < minIndices.X) minIndices.X = GetXandYIndicesFromTileId(tile.Id).X;
                    if (GetXandYIndicesFromTileId(tile.Id).Y > maxIndices.Y) maxIndices.Y = GetXandYIndicesFromTileId(tile.Id).Y;
                    if (GetXandYIndicesFromTileId(tile.Id).Y < minIndices.Y) minIndices.Y = GetXandYIndicesFromTileId(tile.Id).Y;
                }
            }

            Vector3 cornerA3d = baseGame.GraphicsDevice.Viewport.Project(new Vector3(minIndices.X - centralIndexX, centralIndexY + 2.5f - minIndices.Y, 0.5f), baseGame.BasicEffect.Projection,
                                                                   baseGame.BasicEffect.View,
                                                                   baseGame.GetWorldMatrix);
            Vector2 cornerA = new Vector2(cornerA3d.X, cornerA3d.Y);


            Vector3 cornerB3d = baseGame.GraphicsDevice.Viewport.Project(new Vector3(maxIndices.X - centralIndexX, centralIndexY + 2.5f - minIndices.Y, 0.5f), baseGame.BasicEffect.Projection,
                                                                  baseGame.BasicEffect.View,
                                                                  baseGame.GetWorldMatrix);
            Vector2 cornerB = new Vector2(cornerB3d.X, cornerB3d.Y);


            Vector3 cornerC3d = baseGame.GraphicsDevice.Viewport.Project(new Vector3(minIndices.X-centralIndexX-2, 0.5f+centralIndexY-minIndices.Y, 0.5f), baseGame.BasicEffect.Projection,
                                                                   baseGame.BasicEffect.View,
                                                                   baseGame.GetWorldMatrix);
            Vector2 cornerC = new Vector2(cornerC3d.X, cornerC3d.Y);

            Vector3 cornerD3d = baseGame.GraphicsDevice.Viewport.Project(new Vector3(minIndices.X-centralIndexX-2, 0.5f+centralIndexY-maxIndices.Y, 0.5f), baseGame.BasicEffect.Projection,
                                                                               baseGame.BasicEffect.View,
                                                                               baseGame.GetWorldMatrix);
            Vector2 cornerD = new Vector2(cornerD3d.X, cornerD3d.Y);

            for (int x = (int)minIndices.X; x <= maxIndices.X; x++)
            {
                Vector2 designationPosition = cornerA + (cornerB - cornerA) * (int)(x-minIndices.X) / (int)(maxIndices.X-minIndices.X);
                string label = new string((char)('A' + x), 1);
                spriteBatch.DrawString(designationsFont, label, new Vector2(designationPosition.X + 2, designationPosition.Y - 0.05f), Color.Gray);
                spriteBatch.DrawString(designationsFont, label, designationPosition, Color.Yellow);
            }

            for (int y = (int)minIndices.Y; y <= maxIndices.Y; y++)
            {
                Vector2 designationPosition = cornerC + (cornerD - cornerC) * (int)(y-minIndices.Y) / (int)(maxIndices.Y-minIndices.Y);
                spriteBatch.DrawString(designationsFont, Convert.ToString(y+2),new Vector2(designationPosition.X + 2, designationPosition.Y - 0.05f), Color.Gray);
                spriteBatch.DrawString(designationsFont, Convert.ToString(y+2), designationPosition, Color.Yellow);
            }

            spriteBatch.End();
        }
    }
}